package com.pc.ipushpin.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class SignValidator {
	
	private static Logger log = LoggerFactory
			.getLogger(SignValidator.class);

	public static boolean validateSign(Map<String, String> req, String securityKey) {
		String sign = req.get("sign");
		String actualSign = buildSignature(req, securityKey);
		
		return sign == null ? false : sign.equals(actualSign);
	}
	
	/**
     * 生成签名
     * @param req 需要签名的要素
     * @return 签名结果字符串
     */
    public static String buildSignature(Map<String, String> req, String securityKey) {
		String prestr = createValueString(req);
		
		prestr = prestr + "&" + md5(securityKey);
		String sign = md5(prestr);
		return sign;
    }
    
    /**
     * 签名
     * @param req
     * @param securityKey
     * @return
     */
    public static String buildSignature2(Map<String, String> req, String securityKey) {
    	String prestr = createValueString(req);
    	prestr = prestr + "&KEY=" + securityKey;
		return md5(prestr).toUpperCase();
    }
    
    
    /** 
     * 除去请求要素中的空值和签名参数
     * @param para 请求要素
     * @return 去掉空值与签名参数后的请求要素
     */
    public static Map<String, String> paraFilter(Map<String, String> para) {

        Map<String, String> result = new HashMap<String, String>();

        if (para == null || para.size() <= 0) {
            return result;
        }

        for (String key : para.keySet()) {
            String value = para.get(key);
            if (key.equalsIgnoreCase("sign")) {
                continue;
            }
            result.put(key, value);
        }

        return result;
    }
    
    public static String createValueString(Map<String, String> para) {

    	para = paraFilter(para);
    	
        List<String> keys = new ArrayList<String>(para.keySet());
        
        Collections.sort(keys);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = para.get(key);
            
            if (value == null || "".equals(value)) continue;
            
            sb.append(key);
            sb.append("=");
            sb.append(value);
            sb.append("&");
        }
        return sb.toString().substring(0, sb.length()-1);
    }
    
    public static String md5(String str) {

		if (str == null) {
			return null;
		}

		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {

			return str;
		} catch (UnsupportedEncodingException e) {
			return str;
		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}

		return md5StrBuff.toString();
	}
    
	/**
	 * Map key,value 非空校验
	 * 
	 * @param para
	 *            请求要素
	 * @return 校验结果
	 */
    public static Map<String, Object> checkEmpty(Map<String, String> para) {

		Map<String, Object> map = new HashMap<String, Object>();
		for (String key : para.keySet()) {
			
			String value = para.get(key);
			if (value == null) {
				Map<String,Object> data = new HashMap<>();
				map.put("success", false);
				map.put("code", "107");
				map.put("msg", "业务参数缺失");
				data.put("resultCode", "01");
				map.put("data", data);
				return map;
			}
			if (value.equals("")) {
				Map<String,Object> data = new HashMap<>();
				map.put("success", false);
				map.put("code", "108");
				map.put("msg", "错误的业务参数");
				data.put("resultCode", "01");
				map.put("data", data);
				return map;
			}
		}

		map.put("resultCode", "00");
		map.put("msg", "参数非空校验通过");

		return map;
	}
    public static void main(String[] args) {
//    	Map<String, String> req = new HashMap<String, String>();
//    	req.put("pid", "12306");
//    	req.put("service", " GetTrainTimeTableXml");
//    	req.put("from", "杭州");
//    	req.put("to", "北京");
//    	req.put("date", "2012-01-10");
//    	req.put("sign", "31A443092189FD7110A8F07163807295");
//		System.out.println(validateSign(req, "hhf2ykbui8ff2cfewdap1tyimwjkaad2"));
    	
    	System.out.println(md5("appId=430073160120002&appName=火车票&appkey=66712BE8BC9DF66EF77790F14B208549&backEndUrl=http://58.252.75.158:8889/back/trainTicket/trainTicketNotify&bussid=731169&orderMoney=1000&orderNumber=20150108123456&ordertimeout=1000&productName=火车票&rekey=66712BE8BC9DF66EF77790F14B208549&signMethod=MD5&userId=96240752&version=1.0.0&95ed74437477cafd5967f8f883d12a88"));
	}
}
